#ifndef JAE_LOGGER_H_
#define JAE_LOGGER_H_

#include <iostream>
#include <fstream>

#include "version.h"
#include "defines.h"

/****************************************************//**
 * Project-Namespace
 ********************************************************/
namespace jae
{
    /****************************************************//**
     * The logger writes messages to a logfile.
     ********************************************************/
  class Logger
  {
    public:
    	Logger();

        void createNewLogFile();

        template<class TemplateClass>
        void write(TemplateClass aValue);

        template<class TemplateClass>
        void writeln(TemplateClass aValue);
        
        template<class TemplateClass>
        void error(const char* aErrorTitle, const char* aFunctionName, TemplateClass aMessage);

    private:
        const char* getTime(void);
        bool open();
        void close();
        std::ofstream _logFile;
  };

  /****************************************************//**
   * This method writes any standard type in the logfile.
   * @param aValue write content
   * @param aNewLine write new line
   ********************************************************/
  template<class TemplateClass>
  void Logger::write(TemplateClass aValue)
  {
    if (this->open())
    {
      _logFile << aValue;
      this->close(); 
    }
    
    std::cout << aValue;
    std::flush(std::cout);
  }
  

  /****************************************************//**
   * This method writes any standard type in the logfile.
   * @param aValue write content
   * @param aNewLine write new line
   ********************************************************/
  template<class TemplateClass>
  void Logger::writeln(TemplateClass aValue)
  {
    if (this->open())
    {
        _logFile << aValue << std::endl
                  << "--------------------------------------- "
                  << getTime();
        this->close(); 
    }
    
    std::cout << aValue << std::endl
              << "--------------------------------------- "
              << getTime();
    std::flush(std::cout);
  }
  
  /****************************************************//**
   * This method writes an errormessage to the logfile.
   * @param aFunctionName source of the error
   * @param aMessage text of the message
   * @param aErrorTitle errortype ("ERROR", "NOT YET IMPLEMENTED", ...)
   ********************************************************/
  template<class TemplateClass>
  void Logger::error(const char* aErrorTitle, const char* aFunctionName, TemplateClass aMessage)
  { //TODO Callstack implementieren (siehe Workspaceverzeichnis "callstack")
      if (this->open())
      {
          _logFile << ">>> " << aErrorTitle << " <<< " << getTime() 
                   << "  [ " << aFunctionName << " ]"  << std::endl
                   << "  " << aMessage << std::endl;
          this->close();
      }
      
      std::cout << ">>> " << aErrorTitle << " <<< " << getTime()
                << "  [ " << aFunctionName << " ]"  << std::endl
                << "  " << aMessage << std::endl;
      std::flush(std::cout);
  }
  
} //namespace jae

#endif // JAE_LOGGER_H_
